<script>
    //----------------------------------
    //定义全局常量
    //----------------------------------
    var GL_CONS = {};

    /** 秦丝科技系列产品店店铺地址  */
    GL_CONS.QINSILK_TAOBAO_SHOP = "https://shop120446283.taobao.com/";
    /** 蓝牙热敏打印机  */
    GL_CONS.QINSILK_TAOBAO_ITEM_BTPRINTER = "https://item.taobao.com/item.htm?id=45331394122";
    /** 标签条码打印机 */
    GL_CONS.QINSILK_TAOBAO_ITEM_MULTIPRINTER = "https://item.taobao.com/item.htm?id=522196993884";
    /** 针式打印机蓝牙适配器 */
    GL_CONS.QINSILK_TAOBAO_ITEM_BTADAPTER = "https://item.taobao.com/item.htm?id=521902046468";

    GL_CONS.DEFAULT_COMPANY_LOGO = '/is/template/nadmin/css/themes/sky-blue/img/photos/photo-flower.jpg';

    GL_CONS.VIP_OPEN_URL = '//www.qinsilk.com/vip.html';
    //客户积分
    GL_CONS.CONSUMER_POINT_OPEN_URL = '/mgr/app/openMyAppPage.ac?id=5';
    GL_CONS.CONSUMER_POINT_APP_ID = 5;

    /**
     * 支付类型
     */
    GL_CONS.PAY_TYPE = [
	    {val: "wxpay", text: "微信支付"},
	    {val: "alipayDirect", text: "支付宝"},
	    {val: "voucher", text: "代金券"},
	    {val: "account", text: "账户余额"},
	    {val: "ICBCB2C", text: "中国工商银行"},
	    {val: "BOCB2C", text: "中国银行"},
	    {val: "CMB", text: "招商银行"},
	    {val: "CCB", text: "中国建设银行"},
	    {val: "ABC", text: "中国农业银行"},
	    {val: "SPDB", text: "上海浦东发展银行"},
	    {val: "CIB", text: "兴业银行"},
	    {val: "GDB", text: "广发银行"},
	    {val: "FDB", text: "富滇银行"},
	    {val: "CITIC", text: "中信银行"},
	    {val: "HZCBB2C", text: "杭州银行"},
	    {val: "SHBANK", text: "上海银行"},
	    {val: "NBBANK", text: "宁波银行"},
	    {val: "SPABANK", text: "平安银行"},
	    {val: "POSTGC", text: "中国邮政储蓄银行"},
	    {val: "abc1003", text: "visa"},
	    {val: "abc1004", text: "master"},
	    {val: "ICBCBTB", text: "中国工商银行（B2B）"},
	    {val: "ABCBTB", text: "中国农业银行（B2B）"},
	    {val: "CCBBTB", text: "中国建设银行（B2B）"},
	    {val: "SPDBB2B", text: "上海浦东发展银行（B2B）"},
	    {val: "BOCBTB", text: "中国银行（B2B）"},
	    {val: "CMBBTB", text: "招商银行（B2B）"}

    ];
    //增值服务值常量
    GL_CONS.SERVICE_TYPE_VAL = {
	    SERVICE_RECHARGE: 0,
	    SERVICE_WECHAT_SHOP: 2,
	    SERVICE_ASSOCIATOR: 3,
	    SERVICE_PAY_WITH_BARCODE: 4,
	    SERVICE_CUSTOM_POINT: 5,
	    SERVICE_TEMPLATE_TAILOR: 20,
	    SERVICE_SMS: 17,
	    SERVICE_TRAINNING: 6,
	    SERVICE_ADVISOR: 9,
	    SERVICE_DATA_IMPORT: 10,
	    SERVICE_BUSINESS_CARD: 11,
	    SERVICE_PAY_ONLINE: 7,
	    SERVICE_ONLINE_STORE_CONNECT: 8,
	    SERVICE_PURCHASE_BTPRINTER: 21,
	    SERVICE_PURCHASE_MULTIPRINTER: 22,
	    SERVICE_PURCHASE_BTADAPTER: 23,
	    SERVICE_NEEDLE_PRINTER: 12,
	    SERVICE_CUSTOM_FLOW: 13,
	    SERVICE_PURCHASE_BARCODE_SCANNER: 15,
	    SERVICE_PURCHASE_110MM_BTPRINTER: 16
    };

    /**
     * 增值服务类型
     */
    GL_CONS.SERVICE_TYPE = [
	    {val: GL_CONS.SERVICE_TYPE_VAL.SERVICE_RECHARGE, text: "充值"},
	    {val: GL_CONS.SERVICE_TYPE_VAL.SERVICE_WECHAT_SHOP, text: "销货宝"},
	    {val: GL_CONS.SERVICE_TYPE_VAL.SERVICE_ASSOCIATOR, text: "进销存会员"},
	    {val: GL_CONS.SERVICE_TYPE_VAL.SERVICE_PAY_WITH_BARCODE, text: "扫码支付"},
	    {val: GL_CONS.SERVICE_TYPE_VAL.SERVICE_CUSTOM_POINT, text: "客户积分"},
	    {val: GL_CONS.SERVICE_TYPE_VAL.SERVICE_TEMPLATE_TAILOR, text: "订制打印模板"},
	    {val: GL_CONS.SERVICE_TYPE_VAL.SERVICE_SMS, text: "短信服务"},
	    {val: GL_CONS.SERVICE_TYPE_VAL.SERVICE_TRAINNING, text: "培训服务"},
	    {val: GL_CONS.SERVICE_TYPE_VAL.SERVICE_ADVISOR, text: "专属顾问"},
	    {val: GL_CONS.SERVICE_TYPE_VAL.SERVICE_DATA_IMPORT, text: "初始数据代导入"},
	    {val: GL_CONS.SERVICE_TYPE_VAL.SERVICE_BUSINESS_CARD, text: "订做名片"},
	    {val: GL_CONS.SERVICE_TYPE_VAL.SERVICE_PAY_ONLINE, text: "在线支付"},
	    {val: GL_CONS.SERVICE_TYPE_VAL.SERVICE_ONLINE_STORE_CONNECT, text: "电商接口"},
	    {val: GL_CONS.SERVICE_TYPE_VAL.SERVICE_PURCHASE_BTPRINTER, text: "购买蓝牙打印机"},
	    {val: GL_CONS.SERVICE_TYPE_VAL.SERVICE_PURCHASE_MULTIPRINTER, text: "购买条码标签打印机"},
	    {val: GL_CONS.SERVICE_TYPE_VAL.SERVICE_PURCHASE_BTADAPTER, text: "购买针式打印机蓝牙适配器"},
	    {val: GL_CONS.SERVICE_TYPE_VAL.SERVICE_NEEDLE_PRINTER, text: "购买针式打印机"},
	    {val: GL_CONS.SERVICE_TYPE_VAL.SERVICE_CUSTOM_FLOW, text: "客流量统计"}
    ];


    /**
     * 增值服务状态
     */
    GL_CONS.SERVICE_STATUS = [
	    {val: -1, text: "已撤销"},
	    {val: 1, text: "草稿"},
	    {val: 2, text: "审核中"},
	    {val: 3, text: "待付款"},
	    {val: 4, text: "处理中"},
	    {val: 5, text: "已完成"}
    ];
    /**
     * 服务网点的状态
     */
    GL_CONS.MA_MARKET_STATUS = [
	    {val: 'normal', text: "正常"},
	    {val: 'terminate', text: "已解约"}
    ];

    /**
     * 服务网点的状态
     */
    GL_CONS.GOOD_COST_ALGORITHM_VAL = {
	    AP: "ap",
	    MWA: "mwa"
    };

    /**
     * 服务网点的状态
     */
    GL_CONS.GOOD_COST_ALGORITHM = [
	    {val: GL_CONS.GOOD_COST_ALGORITHM_VAL.AP, text: "全部加权平均"},
	    {val: GL_CONS.GOOD_COST_ALGORITHM_VAL.MWA, text: "移动加权平均"}
    ];

    /**
     * 流水记录业务类别 1-期初余额; 21-采购单，22-采购退货，23-采购结算单,24-付款调整; 31-销售单，32-销售退货，33-销售结算,34-收款调整
     */
    GL_CONS.BANLANCE_BUSINESS_ITEM = [
	    {val: 1, text: "期初余额"},
	    {val: 21, text: "采购单"},
	    {val: 22, text: "采购退货"},
	    {val: 23, text: "采购结算单"},
	    {val: 24, text: "供应商付款"},
	    {val: 25, text: "待入库-采购"},
	    {val: 26, text: "入库单-采购"},
	    {val: 31, text: "销售单"},
	    {val: 32, text: "销售退货"},
	    {val: 33, text: "销售结算"},
	    {val: 34, text: "客户收款"},
	    {val: 35, text: "待出库-销售"},
	    {val: 36, text: "出库单-销售"},
	    {val: 41, text: "前台收银"},
	    {val: 51, text: "库存盘点单"},
	    {val: 52, text: "库存调整单"},
	    {val: 61, text: "库存调拨单"},
	    {val: 62, text: "待出库-调拨"},
	    {val: 63, text: "出库单-调拨"},
	    {val: 64, text: "待入库-调拨"},
	    {val: 65, text: "入库单-调拨"}
    ];

    /**
     *  账户流水交易类型
     */
    GL_CONS.BANLANCE_TRANSACTION_TYPE = [
	    {val: "JH", text: "采购单"},
	    {val: "JT", text: "采购退货单"},
	    {val: "PF", text: "销售单"},
	    {val: "TH", text: "销售退货单"},
	    {val: "LS", text: "零售单"},
	    {val: "SK", text: "收款单"},
	    {val: "FK", text: "付款单"},
	    {val: "JZ_ZHZR", text: "账户转入"},
	    {val: "JZ_ZHZC", text: "账户转出"},
	    {val: "JZ_SRJZ", text: "收入记账"},
	    {val: "JZ_ZCJZ", text: "支出记账"},
	    {val: "CZ", text: "充值"},
	    {val: "WD", text: "销货宝订单"}
    ];

    /**
     *  账户流水结算方式
     */
    GL_CONS.BANLANCE_PAYMENT_METHOD = [
	    {val: "1", text: "现金支付"},
	    {val: "2", text: "在线支付"}
    ];

    /**
     * 流水记录业务单据对应的URL 1-期初余额; 21-采购单，22-采购退货，23-采购结算单,24-付款调整; 31-销售单，32-销售退货，33-销售结算,34-收款调整
     */
    GL_CONS.BANLANCE_BUSINESS_ITEM_REF = [
	    {val: 21, text: base + "/admin/inner/orders/purchase/purchaseList.ac?mid=2&onLoadOrdersSn="},
	    {val: 22, text: base + "/admin/inner/orders/purchase/rejectPurchaseList.ac?mid=2&onLoadOrdersSn="},
	    {val: 23, text: base + "/admin/inner/finance/payment/paymentList.ac?mid=67&onLoadOrdersSn="},
	    {val: 24, text: base + "/admin/inner/finance/paymentAdjust/paymentAdjustList.ac?mid=67&onLoadOrdersSn="},
	    {val: 31, text: base + "/admin/inner/sale/wholesaleOrdersList.ac?mid=4&onLoadOrdersSn="},
	    {val: 32, text: base + "/admin/inner/sale/rejectOrdersList.ac?mid=4&onLoadOrdersSn="},
	    {val: 33, text: base + "/admin/inner/finance/receipt/receiptList.ac?mid=67&onLoadOrdersSn="},
	    {val: 34, text: base + "/admin/inner/finance/receiptAdjust/receiptAdjustList.ac?mid=67&onLoadOrdersSn="},
	    {val: 41, text: base + "/admin/inner/sale/retailOrdersList.ac?mid=4&onLoadOrdersSn="},
	    {val: 51, text: base + "/admin/inner/storehouse/storeOrderList.ac?mid=3&onLoadOrdersSn="},
	    {val: 52, text: base + "/admin/inner/storehouse/storeOrderList.ac?mid=3&onLoadOrdersSn="},
	    {
		    val: 61,
		    text: base + "/admin/inner/storehouse/storeTransferOrder/storeTransferOrderList.ac?mid=3&onLoadOrdersSn="
	    }
    ];
    GL_CONS.BANLANCE_BUSINESS_SN_REF = [
	    {val: 'JH', text: base + "/admin/inner/orders/purchase/purchaseList.ac?mid=2&onLoadOrdersSn="},
	    {val: 'JT', text: base + "/admin/inner/orders/purchase/rejectPurchaseList.ac?mid=2&onLoadOrdersSn="},
	    {val: 'PF', text: base + "/admin/inner/sale/wholesaleOrdersList.ac?mid=4&onLoadOrdersSn="},
	    {val: 'TH', text: base + "/admin/inner/sale/rejectOrdersList.ac?mid=4&onLoadOrdersSn="},
	    {val: 'LS', text: base + "/admin/inner/sale/retailOrdersList.ac?mid=4&onLoadOrdersSn="},
	    {val: 'PD', text: base + "/admin/inner/storehouse/storeOrderList.ac?mid=3&onLoadOrdersSn="},
	    {val: 'IMPORT', text: base + "/admin/inner/storehouse/storeOrderList.ac?mid=3&onLoadOrdersSn="},
	    {
		    val: 'DB',
		    text: base + "/admin/inner/storehouse/storeTransferOrder/storeTransferOrderList.ac?mid=3&onLoadOrdersSn="
	    },
	    {val: 'CK', text: base + "/admin/inner/storehouse/wout/storeOutOrdersList.ac?mid=3&onLoadOrdersSn="},
	    {val: 'RK', text: base + "/admin/inner/storehouse/win/storeInOrdersList.ac?mid=3&onLoadOrdersSn="},
	    {val: 'WD', text: base + "/admin/shop/wechat/memberOrders/memberOrdersList.ac?mid=9&onLoadOrdersSn="}
    ];

    GL_CONS.PROXY_BUSINESS_SN_REF = [
	    {val: 'wholsale', text: base + "/admin/inner/sale/wholesaleOrdersList.ac?mid=4&onLoadOrdersSn="},
	    {val: 'retail', text: base + "/admin/inner/sale/retailOrdersList.ac?mid=4&onLoadOrdersSn="},
	    {val: 'member', text: base + "/admin/shop/wechat/memberOrders/memberOrdersList.ac?mid=9&onLoadOrdersSn="}
    ];

    /**
     * 为方便统一修改，状态图标CSS样式放到这
     */
    GL_CONS.STATE_ICON_CSS = {
	    draft: "draft", //草稿
	    approve: "approve", //已提交
	    inStore: "inStore", //已入库
	    winStore: "winStore",//待入库
	    someInStore: "someInStore",//部分入库
	    woutStore: "woutStore",//待出库
	    someOutStore: "someOutStore",//部分出库
	    received: "inStore", //已收货
	    settle: "settle", //已结算
	    booked: "booked",//正在订货
	    inventory: "inventory",//已盘点
	    transfer: "transfer",//已转进货、销售单
	    waitShip: "waitShip", //备货中，待发货
	    ship: "ship", //已发货
	    receive: "receive",
	    complete: "complete", //已完成
	    destroy: "destroy" //已撤销
    };

    GL_CONS.PAY_ICON_CSS = {
	    wxpayScanPay: "wxpayScanPay",//微信支付
	    alipayBarPay: "alipayBarPay" //支付宝支付
    };


    GL_CONS.HELP_URL = {
	    indexHelp: "//www.qinsilk.com/mms/front/help/help-id0.html", //首页
	    ordersListHelp: "//www.qinsilk.com/mms/front/help/help-id230.html#采购订单", //采购订单
	    purchaseListHelp: "//www.qinsilk.com/mms/front/help/help-id230.html#采购单", //采购单
	    rejectPurchaseListHelp: "//www.qinsilk.com/mms/front/help/help-id277.html#采购退货单", //采购退货单
	    replenishListHelp: "//www.qinsilk.com/mms/front/help/help-id1042.html", //智能补货
	    supplierListHelp: "//www.qinsilk.com/mms/front/help/help-id231.html#供应商管理", //供应商管理
	    supplierRecordListHelp: "//www.qinsilk.com/mms/front/help/help-id236.html", //供应商对帐及收款
	    wholesaleOrdersPreListHelp: "//www.qinsilk.com/mms/front/help/help-id237.html#销售订单", //销售订单
	    wholesaleOrderListHelp: "//www.qinsilk.com/mms/front/help/help-id237.html#销售单", //销售单
	    sendWholesaleOrdersEmailHelp: "//www.qinsilk.com/mms/front/help/help-id237.html#发送销售单据邮件", //发送邮件预览
	    sendOrdersEmailHelp: "//www.qinsilk.com/mms/front/help/help-id230.html#发送采购单据邮件", //发送邮件预览
	    sendClientAccountRecordEmailHelp: "//www.qinsilk.com/mms/front/help/help-id242.html", //发送邮件预览
	    rejectOrdersPreListHelp: "//www.qinsilk.com/mms/front/help/help-id278.html#销售退货申请", //销售退货申请
	    rejectOrdersListHelp: "//www.qinsilk.com/mms/front/help/help-id278.html#销售退货单", //销售退货单
	    checkoutHelp: "//www.qinsilk.com/mms/front/help/help-id240.html#前台收银", //前台收银
	    retailOrdersListHelp: "//www.qinsilk.com/mms/front/help/help-id240.html#前台收银历史", //前台收银历史
	    clientListHelp: "//www.qinsilk.com/mms/front/help/help-id241.html#客户管理", //客户管理
	    clientRecordListHelp: "//www.qinsilk.com/mms/front/help/help-id242.html", //客户对帐及收款
	    clientItemListHelp: "//www.qinsilk.com/mms/front/help/help-id241.html#客户分类", //客户分类
	    goodsStoredListHelp: "//www.qinsilk.com/mms/front/help/help-id251.html", //库存查询
	    storeOrderListHelp: "//www.qinsilk.com/mms/front/help/help-id254.html", //库存盘点单
	    storeTransferOrderListHelp: "//www.qinsilk.com/mms/front/help/help-id253.html", //库存调拨单
	    storehouseListHelp: "//www.qinsilk.com/mms/front/help/help-id256.html", //仓库管理
	    goodsStoredRecordListHelp: "//www.qinsilk.com/mms/front/help/help-id255.html", //库存流水
	    accountRecordListHelp: "//www.qinsilk.com/mms/front/help/help-id257.html", //账户流水
	    accountListHelp: "//www.qinsilk.com/mms/front/help/help-id258.html", //结算账户
	    accountItemListHelp: "//www.qinsilk.com/mms/front/help/help-id259.html", //账目类型
	    salePayRecordListHelp: "http://www.qinsilk.com/mms/front/help/help-id765.html",//支付流水
	    purchaseReportHelp: "//www.qinsilk.com/mms/front/help/help-id265.html", //采购报表
	    saleReportHelp: "//www.qinsilk.com/mms/front/help/help-id266.html", //销售报表
	    clientSaleReportHelp: "//www.qinsilk.com/mms/front/help/help-id268.html", //客户销量
	    saleReportByGoodsHelp: "//www.qinsilk.com/mms/front/help/help-id269.html", //商品销量
	    purchaseVsSaleListHelp: "//www.qinsilk.com/mms/front/help/help-id270.html", //进销对比
	    totalReportHelp: "//www.qinsilk.com/mms/front/help/help-id271.html", //经营汇总
	    goodsListHelp: "//www.qinsilk.com/mms/front/help/help-id244.html#商品管理", //商品管理
	    goodsImportHelp: "//www.qinsilk.com/mms/front/help/help-id244.html#商品导入", //商品导入
	    categoryListHelp: "//www.qinsilk.com/mms/front/help/help-id244.html#商品分类", //商品分类
	    colorListHelp: "//www.qinsilk.com/mms/front/help/help-id244.html#颜色管理", //颜色管理
	    sizeListHelp: "//www.qinsilk.com/mms/front/help/help-id244.html#尺码管理", //尺码管理
	    blandListHelp: "//www.qinsilk.com/mms/front/help/help-id244.html#品牌管理", //品牌管理
	    materialListHelp: "//www.qinsilk.com/mms/front/help/help-id244.html#材质管理", //材质管理
	    styleListHelp: "//www.qinsilk.com/mms/front/help/help-id244.html#款式管理", //款式管理
	    seasonListHelp: "//www.qinsilk.com/mms/front/help/help-id244.html#季节管理", //季节管理
	    unitListHelp: "//www.qinsilk.com/mms/front/help/help-id244.html#单位管理", //单位管理
	    myInfoHelp: "//www.qinsilk.com/mms/front/help/help-id245.html", //个人信息
	    pubUserListHelp: "//www.qinsilk.com/mms/front/help/help-id246.html", //用户管理
	    roleListHelp: "//www.qinsilk.com/mms/front/help/help-id246.html#角色管理", //角色管理
	    comStoreListHelp: "//www.qinsilk.com/mms/front/help/help-id286.html", //门店管理
	    deliveryCompanyListHelp: "//www.qinsilk.com/mms/front/help/help-id248.html", //物流公司
	    bulletinInnerListHelp: "//www.qinsilk.com/mms/front/help/help-id247.html", //系统公告
	    printTemplateHelp: "//www.qinsilk.com/mms/front/help/help-id272.html", //打印模板
	    companyConfigHelp: "//www.qinsilk.com/mms/front/help/help-id249.html",//系统参数
	    operateLogListHelp: "//www.qinsilk.com/mms/front/help/help-id250.html",//系统日志
	    sysResetHelp: "//www.qinsilk.com/mms/front/help/help-id285.html",//系统重置
	    wechatShopHelp: "//www.qinsilk.com/mms/front/help/help-id261.html",//店铺概况
	    commodityListHelp: "//www.qinsilk.com/mms/front/help/help-id262.html",//上架商品
	    memberOrdersListHelp: "//www.qinsilk.com/mms/front/help/help-id263.html",//微店订单处理
	    clientMemberListHelp: "//www.qinsilk.com/mms/front/help/help-id264.html",//微店客户
	    //wechatShopConfigHelp:"//www.qinsilk.com/question/help-it-15.html#hid-60",//店铺设置
	    //wechatShopAccountHelp:"//www.qinsilk.com/question/help-it-15.html#hid-61",//店铺账户管理
	    proxyAccountCashHelp: "//www.qinsilk.com/mms/front/help/help-id260.html",//代收提现
	    barcodeConfigHelp: "//www.qinsilk.com/mms/front/help/help-id244.html#条码管理",//条码
	    clientsImportHelp: "//www.qinsilk.com/mms/front/help/help-id241.html#导入客户", //客户导入
	    storeReportHelp: "//www.qinsilk.com/mms/front/help/help-id267.html", //盘点报表
	    tranfersReportHelp: "//www.qinsilk.com/mms/front/help/help-id504.html",//调拨报表
	    suppliersImportHelp: "//www.qinsilk.com/mms/front/help/help-id231.html#导入供应商", //供应商导入
	    eshopHelp: "//www.qinsilk.com/mms/front/help/help-id287.html#开通淘宝订单处理服务", //网店管理
	    eshopOrderHelp: "//www.qinsilk.com/mms/front/help/help-id287.html#订单处理" //网店订单
    };

    GL_CONS.IMG_NOT_FOUND_URL_50 = '/is/template/nadmin/css/themes/sky-blue/img/common/noImagine50.png';
    GL_CONS.IMG_NOT_FOUND_URL_100 = '/is/template/nadmin/css/themes/sky-blue/img/common/noImagine100.png';

    /**
     * 消息点击类型,tmsOrder|3rdurl|modal
     */
//微店订单
    GL_CONS.MSG_CLI_TYPE_TMS_ORDER = "tmsOrder";
    //点击打开链接
    GL_CONS.MSG_CLI_TYPE_URL = "3rdurl";
    //点击打开内容
    GL_CONS.MSG_CLI_TYPE_MODAL = "modal";
    //用户配置所属设备
    GL_CONS.USER_CONFIG_DEVICE = {
	    pc: 1,
	    mobile: 2,
	    common: 3
    };
    GL_CONS.CHANGE_BUSINESS_TIME_ERROR = "您没有数据补录权限，不可提交或撤销业务日期为今日之前的单据或财务！";
    GL_CONS.CHANGE_BUSINESS_TIME = "changeBusinessTime";

    /**
     * 促销类型
     */
    GL_CONS.PROMOTION_TYPE = {
	    CLIENT_POINT_AS_DISCOUNT: 1, // 会员折扣
	    CLIENT_POINT_AS_AMOUNT: 2, // 积分抵现
	    COUPON: 100 // 优惠券
    }
    GL_CONS.PROMOTION_NAME = {
	    CLIENT_POINT_AS_DISCOUNT: '会员折扣',
	    CLIENT_POINT_AS_AMOUNT: '积分抵现',
	    COUPON: '优惠券'
    }

    /**
     * 区域号码
     */
    GL_CONS.AREA_NUMBER = [
	    {value: "", text: "+86 中国", selected: true},
	    {value: "00886", text: "+886 中国台湾地区"},
	    {value: "0082", text: "+82 韩国"},
	    {value: "0060", text: "+60 马来西亚"},
	    {value: "001", text: "+1 美国"},
	    {value: "00853", text: "+853 中国澳门特别行政区"},
	    {value: "00852", text: "+852 中国香港特别行政区"},
	    {value: "0064", text: "+64 新西兰"},
	    {value: "00355", text: "+355 阿尔巴尼亚"},
	    {value: "00213", text: "+213 阿尔及利亚"},
	    {value: "0093", text: "+93 阿富汗"},
	    {value: "0054", text: "+54 阿根廷"},
	    {value: "00353", text: "+353 爱尔兰"},
	    {value: "0020", text: "+20 埃及"},
	    {value: "00251", text: "+251 埃塞俄比亚"},
	    {value: "00372", text: "+372 爱沙尼亚"},
	    {value: "00971", text: "+971 阿拉伯联合酋长国"},
	    {value: "00297", text: "+297 阿鲁巴"},
	    {value: "00968", text: "+968 阿曼"},
	    {value: "00376", text: "+376 安道尔"},
	    {value: "00244", text: "+244 安哥拉"},
	    {value: "001264", text: "+1264 安圭拉"},
	    {value: "001268", text: "+1268 安提瓜和巴布达"},
	    {value: "0061", text: "+61 澳大利亚"},
	    {value: "0043", text: "+43 奥地利"},
	    {value: "00994", text: "+994 阿塞拜疆"},
	    {value: "00247", text: "+247 阿森松岛"},
	    {value: "001246", text: "+1246 巴巴多斯"},
	    {value: "00675", text: "+675 巴布亚新几内亚"},
	    {value: "001242", text: "+1242 巴哈马"},
	    {value: "00375", text: "+375 白俄罗斯"},
	    {value: "001441", text: "+1441 百慕大"},
	    {value: "0092", text: "+92 巴基斯坦"},
	    {value: "00595", text: "+595 巴拉圭"},
	    {value: "00970", text: "+970 巴勒斯坦"},
	    {value: "00973", text: "+973 巴林"},
	    {value: "00507", text: "+507 巴拿马"},
	    {value: "00359", text: "+359 保加利亚"},
	    {value: "0055", text: "+55 巴西"},
	    {value: "001670", text: "+1670 北马里亚纳群岛"},
	    {value: "00229", text: "+229 贝宁"},
	    {value: "0032", text: "+32 比利时"},
	    {value: "0051", text: "+51 秘鲁"},
	    {value: "00354", text: "+354 冰岛"},
	    {value: "00267", text: "+267 博茨瓦纳"},
	    {value: "001", text: "+1 波多黎各"},
	    {value: "0048", text: "+48 波兰"},
	    {value: "00591", text: "+591 玻利维亚"},
	    {value: "00501", text: "+501 伯利兹"},
	    {value: "00387", text: "+387 波斯尼亚和黑塞哥维那"},
	    {value: "00975", text: "+975 不丹"},
	    {value: "00226", text: "+226 布基纳法索"},
	    {value: "00257", text: "+257 布隆迪"},
	    {value: "00850", text: "+850 朝鲜"},
	    {value: "00240", text: "+240 赤道几内亚"},
	    {value: "0045", text: "+45 丹麦"},
	    {value: "0049", text: "+49 德国"},
	    {value: "00246", text: "+246 迭戈加西亚"},
	    {value: "00670", text: "+670 东帝汶"},
	    {value: "00228", text: "+228 多哥"},
	    {value: "001767", text: "+1767 多米尼克"},
	    {value: "001809", text: "+1809 多米尼加共和国"},
	    {value: "00593", text: "+593 厄瓜多尔"},
	    {value: "00291", text: "+291 厄立特里亚"},
	    {value: "007", text: "+7 俄罗斯"},
	    {value: "0033", text: "+33 法国"},
	    {value: "00298", text: "+298 法罗群岛"},
	    {value: "0039", text: "+39 梵蒂冈"},
	    {value: "00689", text: "+689 法属波利尼西亚"},
	    {value: "00594", text: "+594 法属圭亚那"},
	    {value: "00679", text: "+679 斐济"},
	    {value: "0063", text: "+63 菲律宾"},
	    {value: "00358", text: "+358 芬兰"},
	    {value: "00238", text: "+238 佛得角"},
	    {value: "00500", text: "+500 福克兰群岛"},
	    {value: "0061", text: "+61 茯苓（基林）群岛"},
	    {value: "00220", text: "+220 冈比亚"},
	    {value: "00242", text: "+242 刚果（布）"},
	    {value: "00243", text: "+243 刚果（金）"},
	    {value: "0044", text: "+44 格恩西"},
	    {value: "00299", text: "+299 格陵兰"},
	    {value: "001473", text: "+1473 格林纳达"},
	    {value: "00995", text: "+995 格鲁吉亚"},
	    {value: "0057", text: "+57 哥伦比亚"},
	    {value: "00506", text: "+506 哥斯达黎加"},
	    {value: "00590", text: "+590 瓜德罗普岛"},
	    {value: "001671", text: "+1671 关岛"},
	    {value: "0053", text: "+53 古巴"},
	    {value: "00592", text: "+592 圭亚那"},
	    {value: "00509", text: "+509 海地"},
	    {value: "007", text: "+7 哈萨克斯坦"},
	    {value: "00382", text: "+382 黑山共和国"},
	    {value: "0031", text: "+31 荷兰"},
	    {value: "00599", text: "+599 荷属安的列斯群岛"},
	    {value: "00504", text: "+504 洪都拉斯"},
	    {value: "00233", text: "+233 加纳"},
	    {value: "001", text: "+1 加拿大"},
	    {value: "00855", text: "+855 柬埔寨"},
	    {value: "00241", text: "+241 加蓬"},
	    {value: "00253", text: "+253 吉布提"},
	    {value: "00420", text: "+420 捷克共和国"},
	    {value: "00996", text: "+996 吉尔吉斯斯坦"},
	    {value: "00686", text: "+686 基里巴斯"},
	    {value: "00224", text: "+224 几内亚"},
	    {value: "00245", text: "+245 几内亚比绍"},
	    {value: "00263", text: "+263 津巴布韦"},
	    {value: "001345", text: "+1345 开曼群岛"},
	    {value: "00237", text: "+237 喀麦隆"},
	    {value: "00974", text: "+974 卡塔尔"},
	    {value: "0061", text: "+61 科科斯群岛"},
	    {value: "00385", text: "+385 克罗地亚"},
	    {value: "00269", text: "+269 科摩罗"},
	    {value: "00254", text: "+254 肯尼亚"},
	    {value: "00965", text: "+965 科威特"},
	    {value: "00682", text: "+682 库克群岛"},
	    {value: "00599", text: "+599 库拉索岛"},
	    {value: "00266", text: "+266 莱索托"},
	    {value: "00856", text: "+856 老挝"},
	    {value: "00371", text: "+371 拉脱维亚"},
	    {value: "00961", text: "+961 黎巴嫩"},
	    {value: "00231", text: "+231 利比里亚"},
	    {value: "00218", text: "+218 利比亚"},
	    {value: "00423", text: "+423 列支敦士登"},
	    {value: "00370", text: "+370 立陶宛"},
	    {value: "00262", text: "+262 留尼汪岛"},
	    {value: "0040", text: "+40 罗马尼亚"},
	    {value: "00352", text: "+352 卢森堡"},
	    {value: "00250", text: "+250 卢旺达"},
	    {value: "00261", text: "+261 马达加斯加"},
	    {value: "0044", text: "+44 马恩岛"},
	    {value: "00960", text: "+960 马尔代夫"},
	    {value: "00356", text: "+356 马耳他"},
	    {value: "00265", text: "+265 马拉维"},
	    {value: "00223", text: "+223 马里"},
	    {value: "00230", text: "+230 毛里求斯"},
	    {value: "00222", text: "+222 毛里塔尼亚"},
	    {value: "00389", text: "+389 马其顿"},
	    {value: "00692", text: "+692 马绍尔群岛"},
	    {value: "00596", text: "+596 马提尼克"},
	    {value: "00262", text: "+262 马约特岛"},
	    {value: "001684", text: "+1684 美属萨摩亚"},
	    {value: "001340", text: "+1340 美属维京群岛"},
	    {value: "00976", text: "+976 蒙古"},
	    {value: "00880", text: "+880 孟加拉国"},
	    {value: "001664", text: "+1664 蒙塞拉特"},
	    {value: "0095", text: "+95 缅甸"},
	    {value: "00691", text: "+691 密克罗尼西亚"},
	    {value: "00373", text: "+373 摩尔多瓦"},
	    {value: "00212", text: "+212 摩洛哥"},
	    {value: "00377", text: "+377 摩纳哥"},
	    {value: "00258", text: "+258 莫桑比克"},
	    {value: "0052", text: "+52 墨西哥"},
	    {value: "00264", text: "+264 纳米比亚"},
	    {value: "0027", text: "+27 南非"},
	    {value: "00672", text: "+672 南极洲"},
	    {value: "00500", text: "+500 南乔治亚岛和南桑威奇群岛"},
	    {value: "00211", text: "+211 南苏丹"},
	    {value: "00674", text: "+674 瑙鲁"},
	    {value: "00977", text: "+977 尼泊尔"},
	    {value: "00505", text: "+505 尼加拉瓜"},
	    {value: "00227", text: "+227 尼日尔"},
	    {value: "00234", text: "+234 尼日利亚"},
	    {value: "00683", text: "+683 纽埃"},
	    {value: "00672", text: "+672 诺福克岛"},
	    {value: "0047", text: "+47 挪威"},
	    {value: "00680", text: "+680 帕劳群岛"},
	    {value: "0064", text: "+64 皮特凯恩群岛"},
	    {value: "00351", text: "+351 葡萄牙"},
	    {value: "0081", text: "+81 日本"},
	    {value: "0046", text: "+46 瑞典"},
	    {value: "0041", text: "+41 瑞士"},
	    {value: "00503", text: "+503 萨尔瓦多"},
	    {value: "00381", text: "+381 塞尔维亚"},
	    {value: "00232", text: "+232 塞拉利昂"},
	    {value: "00221", text: "+221 塞内加尔"},
	    {value: "00357", text: "+357 塞浦路斯"},
	    {value: "00248", text: "+248 塞舌尔"},
	    {value: "00685", text: "+685 萨摩亚"},
	    {value: "00966", text: "+966 沙乌地阿拉伯"},
	    {value: "00508", text: "+508 圣彼埃尔和密克隆岛"},
	    {value: "00239", text: "+239 圣多美和普林西比"},
	    {value: "00290", text: "+290 圣赫勒拿岛"},
	    {value: "001869", text: "+1869 圣基茨和尼维斯"},
	    {value: "001758", text: "+1758 圣卢西亚"},
	    {value: "00378", text: "+378 圣马力诺"},
	    {value: "001784", text: "+1784 圣文森特和格林纳丁斯"},
	    {value: "0094", text: "+94 斯里兰卡"},
	    {value: "00421", text: "+421 斯洛伐克"},
	    {value: "00386", text: "+386 斯洛文尼亚"},
	    {value: "0047", text: "+47 斯瓦尔巴群岛和扬马延岛"},
	    {value: "00268", text: "+268 斯威士兰"},
	    {value: "00249", text: "+249 苏丹"},
	    {value: "00597", text: "+597 苏里南"},
	    {value: "00677", text: "+677 所罗门群岛"},
	    {value: "00252", text: "+252 索马里"},
	    {value: "0066", text: "+66 泰国"},
	    {value: "00992", text: "+992 塔吉克斯坦"},
	    {value: "00676", text: "+676 汤加"},
	    {value: "00255", text: "+255 坦桑尼亚"},
	    {value: "001649", text: "+1649 特克斯和凯科斯群岛"},
	    {value: "001868", text: "+1868 特立尼达和多巴哥"},
	    {value: "0090", text: "+90 土耳其"},
	    {value: "00993", text: "+993 土库曼斯坦"},
	    {value: "00216", text: "+216 突尼斯"},
	    {value: "00690", text: "+690 托克劳"},
	    {value: "00688", text: "+688 图瓦卢"},
	    {value: "00681", text: "+681 瓦利斯和富图纳"},
	    {value: "00678", text: "+678 瓦努阿图"},
	    {value: "00502", text: "+502 危地马拉"},
	    {value: "0058", text: "+58 委内瑞拉"},
	    {value: "00673", text: "+673 文莱"},
	    {value: "00256", text: "+256 乌干达"},
	    {value: "00380", text: "+380 乌克兰"},
	    {value: "00598", text: "+598 乌拉圭"},
	    {value: "00998", text: "+998 乌兹别克斯坦"},
	    {value: "00225", text: "+225 象牙海岸"},
	    {value: "0034", text: "+34 西班牙"},
	    {value: "0030", text: "+30 希腊"},
	    {value: "0065", text: "+65 新加坡"},
	    {value: "00687", text: "+687 新喀里多尼亚"},
	    {value: "0036", text: "+36 匈牙利"},
	    {value: "00212", text: "+212 西撒哈拉"},
	    {value: "00963", text: "+963 叙利亚"},
	    {value: "001876", text: "+1876 牙买加"},
	    {value: "00374", text: "+374 亚美尼亚"},
	    {value: "00967", text: "+967 也门"},
	    {value: "0039", text: "+39 意大利"},
	    {value: "00964", text: "+964 伊拉克"},
	    {value: "0098", text: "+98 伊朗"},
	    {value: "0091", text: "+91 印度"},
	    {value: "0062", text: "+62 印度尼西亚"},
	    {value: "0044", text: "+44 英国"},
	    {value: "001284", text: "+1284 英属维京群岛"},
	    {value: "00246", text: "+246 英属印度洋领地"},
	    {value: "00972", text: "+972 以色列"},
	    {value: "00962", text: "+962 约旦"},
	    {value: "0084", text: "+84 越南"},
	    {value: "00260", text: "+260 赞比亚"},
	    {value: "0044", text: "+44 泽西"},
	    {value: "00235", text: "+235 乍得"},
	    {value: "00350", text: "+350 直布罗陀"},
	    {value: "0056", text: "+56 智利"},
	    {value: "00236", text: "+236 中非共和国"}
    ];
    //----------------------------------
    //定义全局常量 end
    //----------------------------------

    /**
     * 获取浏览器标识
     */
    function getWebBrowser() {
	    // 调试代码
	    // return "IE8";
	    var userAgent = navigator.userAgent; //取得浏览器的userAgent字符串
	    var isOpera = userAgent.indexOf("Opera") > -1; //判断是否Opera浏览器
	    var isIE = userAgent.indexOf("compatible") > -1 && userAgent.indexOf("MSIE") > -1 && !isOpera; //判断是否IE浏览器
	    var isFF = userAgent.indexOf("Firefox") > -1; //判断是否Firefox浏览器
	    var isSafari = userAgent.indexOf("Safari") > -1; //判断是否Safari浏览器
	    var isChrome = userAgent.indexOf("Chrome") > -1; //判断是否Chrome浏览器
	    if (isChrome) {
		    return "Chrome";
	    }
	    if (isFF) {
		    return "Firefox";
	    }
	    if (isSafari) {
		    return "Safari";
	    }
	    if (isOpera) {
		    return "Opera";
	    }
	    if (isIE) {
		    var IE5 = IE55 = IE6 = IE7 = IE8 = false;
		    var reIE = new RegExp("MSIE (\\d+\\.\\d+);");
		    reIE.test(userAgent);
		    var fIEVersion = parseFloat(RegExp["$1"]);
		    IE5 = fIEVersion == 5.0;
		    IE55 = fIEVersion == 5.5;
		    IE6 = fIEVersion == 6.0;
		    IE7 = fIEVersion == 7.0;
		    IE8 = fIEVersion == 8.0;
		    if (IE5) {
			    return "IE5";
		    }
		    if (IE55) {
			    return "IE55";
		    }
		    if (IE6) {
			    return "IE6";
		    }
		    if (IE7) {
			    return "IE7";
		    }
		    if (IE8) {
			    return "IE8";
		    } else {
			    return "IE9+";
		    }
	    } else {
		    return "unknown";
	    }
    }

    /**
     * 使用js获取当前应用名称
     *
     * @returns
     */
    function getContextPath() {
	    var contextPath = document.location.pathname;
	    var index = contextPath.substr(1).indexOf("/");
	    contextPath = contextPath.substr(0, index + 1);
	    delete index;
	    return contextPath;
    }

    /**
     * 把json数组对象srcData中的key值改为keyMaps中对应的值 比如 srcData: [{id: 1, name: '姓名1'}, {id:
     * 2, name: '姓名2'}]; keyMaps : {text:"name",val:"id"}; 则会返回 [{val: 1, text:
     * '姓名1'}, {val: 2, text: '姓名2'}];
     *
     * @param srcData
     * @param keyMaps
     */
    function transKeyMap(srcData, keyMaps) {
	    if (keyMaps === undefined || undefined === "") {
		    return srcData;
	    }
	    for (var i = 0; i < srcData.length; i++) {
		    for (var srcObject in srcData[i]) {
			    for (var keyMap in keyMaps) {
				    if (srcObject === keyMaps[keyMap]) {
					    srcData[i][keyMap] = srcData[i][srcObject];
				    }

			    }

		    }
	    }
	    return srcData;
    }

    // 除法
    function accDiv(arg1, arg2) {
	    var t1 = 0, t2 = 0, r1, r2;
	    try {
		    t1 = arg1.toString().split(".")[1].length;
	    } catch (e) {
	    }
	    try {
		    t2 = arg2.toString().split(".")[1].length;
	    } catch (e) {
	    }
	    with (Math) {
		    r1 = Number(arg1.toString().replace(".", ""));
		    r2 = Number(arg2.toString().replace(".", ""));
		    return accMul((r1 / r2), pow(10, t2 - t1));
	    }
    }

    /**
     * 对两个值进行除法运算，并将运算结果进行百分比运算，然后再讲运算结果按照小数点位数进行运算
     * @arg1 被除数
     * @arg2 除数
     * @arg3 小数位 默认：2
     * @precision
     */
    function accDivAndSetScale(arg1, arg2, arg3) {
	    return setScale(accDiv(accMul(arg1, arg2), 100), arg3 || 2);
    }

    // 乘法
    function accMul(arg1, arg2) {
	    var m = 0, s1 = arg1.toString(), s2 = arg2.toString();
	    try {
		    m += s1.split(".")[1].length;
	    } catch (e) {
	    }
	    try {
		    m += s2.split(".")[1].length;
	    } catch (e) {
	    }
	    return Number(s1.replace(".", "")) * Number(s2.replace(".", ""))
		    / Math.pow(10, m);
    }

    // 加法
    function accAdd(arg1, arg2) {
	    var r1, r2, m;
	    try {
		    r1 = arg1.toString().split(".")[1].length;
	    } catch (e) {
		    r1 = 0;
	    }
	    try {
		    r2 = arg2.toString().split(".")[1].length;
	    } catch (e) {
		    r2 = 0;
	    }
	    m = Math.pow(10, Math.max(r1, r2));
	    return (arg1 * m + arg2 * m) / m;
    }

    // 减法
    function accSub(arg1, arg2) {
	    var r1, r2, m, n;
	    try {
		    r1 = arg1.toString().split(".")[1].length;
	    } catch (e) {
		    r1 = 0;
	    }
	    try {
		    r2 = arg2.toString().split(".")[1].length;
	    } catch (e) {
		    r2 = 0;
	    }
	    m = Math.pow(10, Math.max(r1, r2));
	    n = (r1 >= r2) ? r1 : r2;
	    return ((arg1 * m - arg2 * m) / m).toFixed(n);
    }

    //四舍五入截取小数位,返回数值对象
    function setScale(a, n) {
	    var value;
	    try {
		    value = accDiv(Math.round(accMul(a, Math.pow(10, n))), Math.pow(10, n));

	    } catch (e) {
		    return a;
	    }

	    return value;
    }

    //先四舍五入，然后用toFixed返回
    function setScaleToFixed(a, n) {
	    var value;
	    try {
		    value = accDiv(Math.round(accMul(a, Math.pow(10, n))), Math.pow(10, n)).toFixed(n);

	    } catch (e) {
		    return a;
	    }

	    return value;
    }

    //取绝对值
    function accAbs(arg1) {
	    var value;
	    try {
		    value = Math.abs(arg1);
	    } catch (e) {
		    value = 0;
	    }
	    return value;
    }

    /**
     * 从数组中，把对象的ID提出来拼成字符串,如1,2,3
     * @param objArray 对象数组
     * @param keyName 所要提取属性的名称
     * @param splitChar拼接分隔符
     * @returns {string}
     */
    function objectArrayToIdString(objArray, keyName, splitChar) {
	    var idStr = "";
	    for (var i = 0; i < objArray.length; i++) {
		    if (i == objArray.length - 1) {
			    idStr += objArray[i][keyName];
		    } else {
			    idStr += objArray[i][keyName] + splitChar;
		    }
	    }
	    return idStr;
    }

    /**
     * 从数组中，把对象的ID提出来放到新的数组中,如[1,2,3]
     * @param objArray 对象数组
     * @param keyName 所要提取属性的名称
     * @returns {string}
     */
    function objectArrayToIdArray(objArray, keyName) {
	    var idArray = [];
	    for (var i = 0; i < objArray.length; i++) {
		    idArray.push(objArray[i][keyName]);
	    }
	    return idArray;
    }

    /**
     * 从数组中，根据对象ID拼成字符串找到对应的对象
     * @param objArrayContainer
     * @param idString
     * @param keyName
     * @param splitChar
     * @returns {Array}
     */
    function idStringToObjectArray(objArrayContainer, idString, keyName, splitChar) {
	    var resultArray = [];
	    if (idString == undefined || idString == '') {
		    return resultArray;
	    }
	    var ids = idString.split(splitChar);
	    for (var j = 0; j < objArrayContainer.length; j++) {
		    for (var i = 0; i < ids.length; i++) {
			    if (ids[i] == objArrayContainer[j][keyName]) {
				    resultArray.push(objArrayContainer[j]);
				    break;
			    }
		    }
	    }
	    return resultArray;
    }

    /**
     * 从对象数组中，取出key对应的值为obj的位置
     * @param array
     * @param obj
     * @param key
     * @returns {*}
     */
    function keyIndexOfArr(obj, array, key) {
	    if (array && array.length > 0) {
		    for (var i = 0; i < array.length; i++) {
			    if (array[i][key] == obj) {
				    return i;
			    }
		    }
		    return -1;
	    } else {
		    return -1;
	    }
    }

    /**
     * 从对象数组中，取出keyName对应的值为value的第一个对象
     * @param arr
     * @param keyName
     * @param value
     * @returns {*}
     */
    function getObject(arr, keyName, value) {
	    if (angular.isArray(arr)) {
		    for (var i = 0; i < arr.length; i++) {
			    if (arr[i] && angular.equals(arr[i][keyName], value)) {
				    return arr[i];
			    }
		    }
	    }
	    return undefined;
    }

    /**
     * 从对象数组中，取出几个key的值都和paramObject中几个key的值一一对应的对象
     * @param arr
     * @param paramObject 获取对象数据的参数,格式如{goodsSn:'sn001',colorId:201,sizeId:232}
     * @returns {*}
     */
    function getObjectByObject(arr, paramObject) {
	    var equalFlag;
	    if (angular.isArray(arr)) {
		    for (var i = 0; i < arr.length; i++) {
			    equalFlag = true;

			    for (var property in paramObject) {
				    if (!angular.equals(arr[i][property], paramObject[property])) {
					    equalFlag = false;
					    break;
				    }
			    }

			    if (equalFlag) {
				    return arr[i];
			    }
		    }
	    }
	    return undefined;
    }

    /**
     * 从对象数组中，取出keyName对应的值为value的对象数组
     * @param arr
     * @param keyName
     * @param value
     * @returns {*}
     */
    function getObjectList(arr, keyName, value) {
	    var resultArray = [];
	    if (angular.isArray(arr)) {
		    for (var i = 0; i < arr.length; i++) {
			    if (angular.equals(arr[i][keyName], value)) {
				    resultArray.push(arr[i]);
			    }
		    }
	    }
	    return resultArray;
    }

    /**
     * 判断数组中是否包含某个对象
     * @param arr 数组
     * @param item 对象
     * @returns {Boolean}
     */
    function contains(arr, item) {
	    if (angular.isArray(arr)) {
		    for (var i = 0; i < arr.length; i++) {
			    if (angular.equals(arr[i], item)) {
				    return true;
			    }
		    }
	    }
	    return false;
    }

    /**
     * 判断数组中是否包含key对应的值为value的对象
     * @param arr
     * @param key
     * @param value
     * @returns {Boolean}
     */
    function containsValue(arr, key, value) {
	    if (angular.isArray(arr)) {
		    for (var i = 0; i < arr.length; i++) {
			    if (angular.equals(arr[i][key], value)) {
				    return true;
			    }
		    }
	    }
	    return false;
    }

    // add
    function add(arr, item) {
	    arr = angular.isArray(arr) ? arr : [];
	    for (var i = 0; i < arr.length; i++) {
		    if (angular.equals(arr[i], item)) {
			    return;
		    }
	    }
	    arr.push(item);
    }

    // remove
    function remove(arr, item) {
	    if (angular.isArray(arr)) {
		    for (var i = 0; i < arr.length; i++) {
			    if (angular.equals(arr[i], item)) {
				    arr.splice(i, 1);
				    return;
			    }
		    }
	    }
    }

    /**
     * 从数组中删除key对应的值为value的一条数据
     * @param arr
     * @param key
     * @param value
     */
    function removeByKey(arr, key, value) {
	    if (angular.isArray(arr)) {
		    for (var i = 0; i < arr.length; i++) {
			    if (angular.equals(arr[i][key], value)) {
				    arr.splice(i, 1);
				    return;
			    }
		    }
	    }
    }

    //从url中提取菜单id
    (function ($) {
	    /**
	     * 获取当前Url参数
	     */
	    $.getUrlParam = function (name) {
		    var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
		    var r = window.location.search.substr(1).match(reg);
		    if (r != null)
			    return unescape(r[2]);
		    return null;
	    };
	    /**
	     * 返回的是当前字符串形式的参数，例如：class_id=3&id=2&
	     */
	    $.getUrlParamStr = function () {
		    var q = location.search.substr(1);
		    var qs = q.split('&');
		    var argStr = '';
		    if (qs) {
			    for (var i = 0; i < qs.length; i++) {
				    argStr += qs[i].substring(0, qs[i].indexOf('=')) + '=' + qs[i].substring(qs[i].indexOf('=') + 1) + '&';
			    }
		    }
		    return argStr;
	    };

	    /**
	     * 当前URL中的对象形式的参数
	     */
	    $.getCurParamObject = function () {
		    var args = new Object();
		    var query = location.search.substring(1);//获取查询串
		    var pairs = query.split(",");//在逗号处断开
		    for (var i = 0; i < pairs.length; i++) {
			    var pos = pairs[i].indexOf('=');//查找name=value
			    if (pos == -1) {//如果没有找到就跳过
				    continue;
			    }
			    var argname = pairs[i].substring(0, pos);//提取name
			    var value = pairs[i].substring(pos + 1);//提取value
			    args[argname] = unescape(value);//存为属性
		    }
		    return args;//返回对象
	    };

	    /**
	     * 指定URL中的对象形式的参数
	     */
	    $.getUrlParamObject = function (url) {
		    var theRequest = new Object();
		    var pos = url.indexOf("?");
		    if (pos != -1) {
			    var str = url.substr(pos + 1);
			    strs = str.split("&");
			    for (var i = 0; i < strs.length; i++) {
				    theRequest[strs[i].split("=")[0]] = unescape(strs[i].split("=")[1]);
			    }
		    }
		    return theRequest;
	    };
	    /**
	     * 取出URL路径部分
	     *
	     * @param url
	     * @returns {String}
	     */
	    $.getUrlPagePath = function (url) {
		    var pagePath = url;
		    var pos = url.indexOf("?");
		    if (pos != -1) {
			    var pagePath = url.substr(0, pos);
		    }
		    return pagePath;
	    };

	    $.gotoPage = function (url, mid) {
		    var urlParams = $.getUrlParamObject(url);
		    var urlParamsStr = '';

		    if (mid == undefined) {
			    mid = getActiveMId();
		    }
		    urlParams['mid'] = mid;

		    $.each(urlParams, function (key, value) {
			    urlParamsStr += (key + "=" + value + "&");
		    });
		    var toUrl = $.getUrlPagePath(url) + "?" + urlParamsStr;
		    window.location.href = toUrl;
	    };
    })(jQuery);

    /**
     * 从url中提取菜单id
     * @returns
     */
    function getActiveMId() {
	    var mid = $.getUrlParam("mid");
	    if (mid == undefined) {
		    mid = 1;
	    }
	    return mid;
    };

    /**
     * jqgrid折扣格式化
     */
    function discount(val, opt, row) {
	    val = parseFloat(val);
	    if (val != undefined && !isNaN(val) && ((typeof val == 'string' && val != '') || (typeof val == 'number' && val >= 0))) {
		    return Math.round(val * 100) / 100;
	    } else {
		    return 100;
	    }
    };

    /**
     * 操作项格式化，适用于对日期月日加粗的列
     */
    function timeFormat(val, opt, row) {
	    var date = new Date(val);
	    var html_con = date.Format("yyyy-") + '<strong>' + date.Format("MM-dd") + '</strong>' + date.Format(" hh:mm");
	    return html_con;
    };

    /**
     * 日期格式化（不包含时点）
     * @param val
     * @param opt
     * @param row
     * @returns
     */
    function dateFormat(val, opt, row) {
	    var date = new Date(val);
	    var html_con = date.Format("yyyy-") + '<strong>' + date.Format("MM-dd") + '</strong>';
	    return html_con;
    }

    /**
     * 操作项格式化，适用于有“修改、删除”操作的表格
     */
    function pubOperUpdateDel(val, opt, row) {
	    var html_con = '<div class="operating" ><span class="ui-icon ui-icon-trash" onclick="delRow(event,' + '\'' + opt.rowId + '\'' + ')"  title="删除"></span><span class="ui-icon ui-icon-pencil" onclick="updateRow(event,' + '\'' + opt.rowId + '\'' + ')"  title="修改"></span></div>';
	    return html_con;
    };

    /**
     * 操作项格式化，适用于有“增加、修改、删除”操作的表格
     */
    function pubOperAddUpdateDel(val, opt, row) {
	    var html_con = '<div class="operating" ><span class="ui-icon ui-icon-plus" onclick="insertEmptyRow(event,' + '\'' + opt.rowId + '\'' + ')" title="新增"></span><span class="ui-icon ui-icon-trash" onclick="delRow(event,' + '\'' + opt.rowId + '\'' + ')"  title="删除"></span><span class="ui-icon ui-icon-pencil" onclick="updateRow(event,' + '\'' + opt.rowId + '\'' + ')"  title="修改"></span></div>';
	    return html_con;
    };

    /**
     * 操作项格式化，适用于有“修改、删除、复制”操作的表格
     */
    function pubOperUpdateDelCopy(val, opt, row) {
	    var html_con = '<div class="operating" ><span class="ui-icon ui-icon-trash" onclick="delRow(event,' + '\'' + opt.rowId + '\'' + ')"  title="删除"></span><span class="ui-icon ui-icon-pencil" onclick="updateRow(event,' + '\'' + opt.rowId + '\'' + ')"  title="修改"></span><span class="ui-icon ui-icon-copy" onclick="copyRow(event,' + '\'' + opt.rowId + '\'' + ')"  title="复制"></span></div>';
	    return html_con;
    };

    /**
     * 操作项格式化，适用于有“新增、删除”操作的表格
     * @param val
     * @param opt
     * @param row
     * @returns {String}
     */
    function pubBillsOper(val, opt, row) {
	    var html_con = '<div class="operating" ><span class="ui-icon ui-icon-plus" onclick="insertEmptyRow(event,' + '\'' + opt.rowId + '\'' + ')" title="新增行"></span><span class="ui-icon ui-icon-trash" onclick="delRow(event,' + '\'' + opt.rowId + '\'' + ')"  title="删除行"></span></div>';
	    return html_con;
    };

    /**
     * 操作项格式化，适用于有“删除”操作的表格
     * @param val
     * @param opt
     * @param row
     * @returns {String}
     */
    function pubBillsOperDel(val, opt, row) {
	    var html_con = '<div class="operating" ><span class="ui-icon ui-icon-trash" onclick="delRow(event,' + '\'' + opt.rowId + '\'' + ')"  title="删除行"></span></div>';
	    return html_con;
    };


    /**
     * 状态格式化为图标的html拼装函数
     * @param allVal 所有状态 [{val:1,text:"草稿",css:"glyphicon glyphicon-edit"},]
     * @param val 当前状态
     * @returns {String}
     */
    function stateFormat(allVal, val) {

	    var html_con = "";

	    for (var i = 0; i < allVal.length; i++) {
		    if (allVal[i].val == val) {
			    return '<div class="grid-state"><span class="' + allVal[i].css + '" title="' + allVal[i].text + '"></span></div>';
		    }
	    }

	    return html_con;
    };

    /**
     * 展示在出入库上的业务单据类型
     *
     * 后续可以考虑做图标优化
     */
    GL_CONS.ORDER_TYPE = [
	    {val: 1, text: '销售单'},
	    {val: 2, text: '采购单'},
	    {val: 3, text: '调拨单'}
    ];

    /**
     * 格式化出入库单据的业务单据类型
     *
     * @param val   单据类型
     * @returns
     */
    function orderTypeFormat(val) {
	    for (var i = 0; i < GL_CONS.ORDER_TYPE.length; i++) {
		    var orderType = GL_CONS.ORDER_TYPE[i];
		    if (val == orderType.val) {
			    return orderType.text;
		    }
	    }
    }

    /**
     * 状态格式化为图标的html拼装函数
     * @param allVal 所有状态 [{val:1,text:"草稿",css:"glyphicon glyphicon-edit"},]
     * @param val 当前状态
     * @returns {String}
     */
    function stateFormatForWholesaleOrders(allVal, val, payTypeAll, pays) {

	    var html_con = "";

	    var state = "";

	    for (var i = 0; i < allVal.length; i++) {
		    if (allVal[i].val == val) {
			    state = '<span class="' + allVal[i].css + '" title="' + allVal[i].text + '"></span>';
		    }
	    }

	    if (val != 1 && pays) {
		    var payIcons = '';
		    for (var i = 0; i < payTypeAll.length; i++) {
			    for (var j = 0; j < pays.length; j++) {
				    if (payTypeAll[i].val == pays[j].payType) {
					    payIcons += '<span class="' + payTypeAll[i].css + '" title="' + payTypeAll[i].text + '"></span>';
				    }
			    }
		    }
		    if (payIcons != '') {
			    return '<div style="line-height: 14px;"  class="grid-state">' + state + payIcons + '</div>';
		    } else {
			    return '<div class="grid-state">' + state + '</div>';
		    }
	    }

	    if (state != "") {
		    return '<div class="grid-state">' + state + '</div>';
	    }

	    return html_con;
    };


    /**
     * 根据元素的ID获取该元素对应的angularjs范围
     * @param id
     * @returns {*}
     */
    function getScope(id) {
	    var ctrl = angular.element(document.getElementById(id));
	    return ctrl.scope();
    }

    function safeApply(scope, fn) {
	    var phase = scope.$root.$$phase;
	    if (phase == '$apply' || phase == '$digest')
		    scope.$eval(fn);
	    else
		    scope.$apply(fn);
    }

    /**
     * 打开新窗口
     * @param url
     */
    function openUrl(url) {
	    var f = document.createElement("form");
	    f.setAttribute("action", url);
	    f.setAttribute("method", 'get');
	    f.setAttribute("target", '_black');
	    document.body.appendChild(f);
	    f.submit();
    }


    /**
     * 对Date的扩展，将 Date 转化为指定格式的String
     * 月(M)、日(d)、小时(h)、分(m)、秒(s)、季度(q) 可以用 1-2 个占位符，
     * 年(y)可以用 1-4 个占位符，毫秒(S)只能用 1 个占位符(是 1-3 位的数字)
     * 例子：
     * (new Date()).Format("yyyy-MM-dd hh:mm:ss.S") ==> 2006-07-02 08:09:04.423
     * (new Date()).Format("yyyy-M-d h:m:s.S") ==> 2006-7-2 8:9:4.18
     *
     */
    Date.prototype.Format = function (fmt) { // author: meizz
	    var o = {
		    "M+": this.getMonth() + 1, // 月份
		    "d+": this.getDate(), // 日
		    "h+": this.getHours(), // 小时
		    "m+": this.getMinutes(), // 分
		    "s+": this.getSeconds(), // 秒
		    "q+": Math.floor((this.getMonth() + 3) / 3), // 季度
		    "S": this.getMilliseconds()
		    // 毫秒
	    };
	    if (/(y+)/.test(fmt))
		    fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "")
			    .substr(4 - RegExp.$1.length));
	    for (var k in o)
		    if (new RegExp("(" + k + ")").test(fmt))
			    fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k])
				    : (("00" + o[k]).substr(("" + o[k]).length)));
	    return fmt;
    };

    /**
     * 把字符串转换成日期
     */
    function stringToDate(str) {
	    if (str == null || str == undefined || str == '') {
		    return;
	    } else {
		    var temp = str.toString();

		    temp = temp.replace(/-/g, "/");

		    var date = new Date(Date.parse(temp));

		    return date;
	    }

    }


    /**
     * 获取日期的最开始时间（0点0分0秒）
     * @param date
     * @returns {String}
     */
    function getDayBeginStr(date) {
	    if (date == null || date == undefined || date == '') {
		    return;
	    } else {
		    return (date.Format("yyyy-MM-dd") + " 00:00:00");
	    }
    }


    /**
     * 将时间转化为GMT时间(通过计算偏移量)，再转换为北京时间
     * @param value 字符串格式的时间变量
     * @returns
     */
    function transferGMTStringtoBJTime(value) {
	    if (value == null || value == undefined || value == '') {
		    return null;
	    }
	    var date = stringToDate(value); //创建一个Date对象
	    if (date == 'Invalid Date') {
		    return null;
	    } else {
		    var offset = 8; 									//北京时间，东8区
		    var bjTime = (date.getTime() + date.getTimezoneOffset() * 60000) + (3600000 * offset);
		    return new Date(bjTime).Format("yyyy-MM-dd hh:mm:ss");
	    }
    };

    /**
     * 获取日期的最开始时间（0点0分0秒）
     * @param date
     * @returns {Date}
     */
    function getDayBegin(date) {
	    return stringToDate(getDayBeginStr(date));
    }

    /**
     * 获取日期N天后的那天的最开始时间（0点0分0秒）
     * @param date
     * @returns {String}
     */
    function getOffsetDayBeginStr(date, offsetDay) {
	    if (date == null || date == undefined || date == '') {
		    return;
	    } else {
		    var targetDate = new Date(date.getTime());
		    targetDate.setDate(targetDate.getDate() + offsetDay);
		    return (targetDate.Format("yyyy-MM-dd") + " 00:00:00");
	    }

    }

    /**
     * 获取日期N天后的那天的最开始时间（0点0分0秒）
     * @param date
     * @returns {Date}
     */
    function getOffsetDayBegin(date, offsetDay) {
	    return stringToDate(getOffsetDayBeginStr(date, offsetDay));
    }

    /**
     * 根据指定的日期返回加减天数之后的日期
     *
     * @param date 指定的日期
     * @param days 可为正负整数，代表加减的天数
     * @returns {Date} 加减后的日期
     */
    function addDate(date, days) {
	    var newDate = new Date(date);
	    newDate.setDate(newDate.getDate() + days);
	    return newDate;
    }

    /**
     * 根据指定的日期返回加减月份数之后的日期
     *
     * @param date 指定的日期
     * @param months 可为正负整数，代表加减的月份数
     * @returns {Date} 加减后的日期
     */
    function addMonth(date, months) {
	    var newDate = new Date(date);
	    newDate.setMonth(newDate.getMonth() + months);
	    return newDate;
    }

    /**
     * 根据指定的日期返回加减年数之后的日期
     *
     * @param date 指定的日期
     * @param years 可为正负整数，代表加减的年数
     * @returns {Date} 加减后的日期
     */
    function addYear(date, years) {
	    var newDate = new Date(date);
	    newDate.setYear(newDate.getYear() + years);
	    return newDate;
    }

    /**
     * 获取当前日期的前一天（昨天）
     *
     * @param date 指定日期
     * @returns {Date} 当前日期的前一天
     */
    function getYesterday(date) {
	    return addDate(date, -1);
    }

    /**
     * 获取当前日期的后一天（明天）
     *
     * @param date 指定日期
     * @returns {Date} 当前日期的后一天
     */
    function getTomorrow(date) {
	    return addDate(date, 1);
    }

    /**
     * 返回指定日期的上个月的日期
     *
     * @param date 指定日期
     * @returns {Date} 指定日期的上个月的日期
     */
    function getLastMonthDate(date) {
	    var newDate = addMonth(date, -1);
	    var vMonth = date.getMonth();
	    var vNewMonth = newDate.getMonth();
	    // 有可能指定日期的月份和上个月指定日期的月份相同。
	    // 比如指定日期为5月31日,求得的newDate为5月1日,此时应该返回4月30日
	    if (vMonth == vNewMonth) {
		    var firstDate = new Date(date.getFullYear(), date.getMonth(), 1);
		    return getYesterday(firstDate);
	    } else {
		    return newDate;
	    }
    }

    /**
     * 返回指定日期的下个月的日期
     *
     * @param date 指定日期
     * @returns {Date} 指定日期的下个月的日期
     */
    function getNextMonthDate(date) {
	    return addMonth(date, 1);
    }

    /**
     * 返回指定日期的去年的日期
     *
     * @param date 指定日期
     * @returns {Date} 指定日期的去年的日期
     */
    function getLastYearDate(date) {
	    return addYear(date, -1);
    }

    /**
     * 返回指定日期的明年的日期
     *
     * @param date 指定日期
     * @returns {Date} 指定日期的明年的日期
     */
    function getNextYearDate(date) {
	    return addYear(date, 1);
    }

    /**
     * 判断两个日期的年月日是否一样
     *
     * @param one 指定日期
     * @param two 指定日期
     */
    function dateIsEquals(one, two, format) {
	    if (one instanceof Date && two instanceof Date && Object.prototype.toString.call(format) === '[object String]') {
		    throw "参数类型不合法！"
	    }
	    if (!format) {
		    format = 'yyyy-MM-dd';
	    }
	    return one.Format(format) == two.Format(format);
    }

    /**
     * 对分组数据进行合并
     * @param groupArray 分组后的数据
     * @returns {Array}
     */

    function mergeBySn(groupArray) {
	    var mergeArray = [];
	    for (var key in groupArray) {
		    var groupList = groupArray[key];  //当前分组数据
		    var groupLen = groupList.length;
		    var mergeObj = {
			    goodsSn: groupList[0].goodsSn,
			    goodName: groupList[0].goodName,
			    colorName: groupList[0].colorName,
			    sizeName: groupList[0].sizeName,
			    unit: groupList[0].unit,
			    quantity: 0,
			    truePrice: 0.00,
			    trueAmount: 0.00
		    }; //第一个元素的信息赋值到合并对象中
		    for (var j = 0; j < groupLen; j++) {
			    mergeObj.quantity += groupList[j].quantity;
			    mergeObj.truePrice += groupList[j].truePrice;
			    mergeObj.trueAmount += groupList[j].trueAmount;
		    }
		    mergeArray.push(mergeObj);
	    }

	    return mergeArray;
    }

    /**
     * 对数组对象按某个属性进行分组
     * @param oriArray 源数组
     * @param groupKeys 分组属性keys,以数组的形式传
     * @returns {{}}
    */
    function group(oriArray, groupKeys) {
	    var groupArray = {}; //分组存放数组
	    var len = oriArray.length;
	    for (var i = 0; i < len; i++) {
		    var oriObj = oriArray[i]; //原始对象
		    var strGroupKey = "";  //分组key值
		    for (var j = 0; j < groupKeys.length; j++) {
			    strGroupKey += oriObj[groupKeys[j]] + "-";
		    }
		    if (groupArray[strGroupKey] == undefined) {
			    var list = [];
			    list.push(oriObj);
			    groupArray[strGroupKey] = list;
		    } else {
			    groupArray[strGroupKey].push(oriObj);
		    }
	    }
	    return groupArray;
    }

    /**
     * 对数组进行排序
     * @param arr
     * @param attribute
     * @returns {Array}
     */
    function sortFunction(arr, attribute) {
	    var array = [];
	    for (var objectKey in arr) {
		    array.push(arr[objectKey]);
	    }

	    array.sort(function (a, b) {
		    return (a[attribute] > b[attribute] ? 1 : -1);

	    });
	    return array;
    }

    //---------------------------------
    //通用过滤器
    //---------------------------------
    var commonFilterApp = angular.module('JxApp.filter', []);

    /**
     * 格式化过滤器
     * @param input 当前项的值
     * @param arr 所有值数组
     * @param keyName 传入input值对应的键名,默认值为'val'
     * @param valName 需要获取的值对应的键名,默认值为'text'
     * @return text  返回valName键名对应的值
     */
    commonFilterApp.filter('typeFormat', function () {
	    var typeFormatFilter = function (input, arr, keyName, valName) {
		    if (input != undefined) {
			    keyName = keyName || 'val';
			    valName = valName || 'text';
			    var accType = getObject(arr, keyName, input);
			    var showString = "";
			    if (accType != undefined) {
				    showString = accType[valName];
			    }
			    return showString;
		    }
		    return input;
	    };
	    return typeFormatFilter;
    });

    /**
     * cutlength 过滤器。如果字符串input长度小于等于cutlength，则原样返回，否则返回前cutlength的字符外加ellipsis号
     * @param input 输入内容
     * @param cutlength 截取的长度
     * @param ellipsis 超长截取后追加的内容
     * @returns 如果字符串input长度小于等于cutlength，则原样返回，否则返回前cutlength的字符外加ellipsis号
     */
    commonFilterApp.filter('cutlength', function () {
	    var cutlengthFilter = function (input, cutlength, ellipsis) {
		    if (input != undefined) {
			    if (input.length > cutlength) {
				    return input.substr(0, cutlength) + ellipsis;
			    } else {
				    return input;
			    }
		    } else {
			    return input;
		    }
	    };
	    return cutlengthFilter;
    });

    /**
     * 格式化过滤器,与jqGrid中的formatter的格式化函数quantity对应
     * @param input 当前项的值
     * @return text  返回格式化后的数字
     */
    commonFilterApp.filter('quantity', function () {
	    var typeFormatFilter = function (input) {
		    if (input != undefined) {
			    return quantity(input);
		    }
		    return input;
	    };
	    return typeFormatFilter;
    });

    //自定义currencyFilter
    commonFilterApp.filter('precisionFilter', ['$locale', function ($locale) {
	    var formats = $locale.NUMBER_FORMATS;
	    var DECIMAL_SEP = '.';

	    function getPrecision() {
		    return getPricePrecision();
	    };


	    function formatNumber(number, pattern, groupSep, decimalSep, fractionSize) {
		    if (isNaN(number) || !isFinite(number)) return '';

		    var isNegative = number < 0;
		    number = Math.abs(number);
		    var numStr = number + '',
			    formatedText = '',
			    parts = [];

		    var hasExponent = false;
		    if (numStr.indexOf('e') !== -1) {
			    var match = numStr.match(/([\d\.]+)e(-?)(\d+)/);
			    if (match && match[2] == '-' && match[3] > fractionSize + 1) {
				    numStr = '0';
			    } else {
				    formatedText = numStr;
				    hasExponent = true;
			    }
		    }

		    if (!hasExponent) {
			    var fractionLen = (numStr.split(DECIMAL_SEP)[1] || '').length;

			    // determine fractionSize if it is not specified
			    if (angular.isUndefined(fractionSize)) {
				    fractionSize = Math.min(Math.max(pattern.minFrac, fractionLen), pattern.maxFrac);
			    }

			    var pow = Math.pow(10, fractionSize);
			    number = Math.round(number * pow) / pow;
			    var fraction = ('' + number).split(DECIMAL_SEP);
			    var whole = fraction[0];
			    fraction = fraction[1] || '';

			    var i, pos = 0,
				    lgroup = pattern.lgSize,
				    group = pattern.gSize;

			    if (whole.length >= (lgroup + group)) {
				    pos = whole.length - lgroup;
				    for (i = 0; i < pos; i++) {
					    if ((pos - i) % group === 0 && i !== 0) {
						    formatedText += groupSep;
					    }
					    formatedText += whole.charAt(i);
				    }
			    }

			    for (i = pos; i < whole.length; i++) {
				    if ((whole.length - i) % lgroup === 0 && i !== 0) {
					    formatedText += groupSep;
				    }
				    formatedText += whole.charAt(i);
			    }

			    // format fraction part.
			    while (fraction.length < fractionSize) {
				    fraction += '0';
			    }

			    if (fractionSize && fractionSize !== "0") formatedText += decimalSep + fraction.substr(0, fractionSize);
		    } else {

			    if (fractionSize > 0 && number > -1 && number < 1) {
				    formatedText = number.toFixed(fractionSize);
			    }
		    }

		    parts.push(isNegative ? pattern.negPre : pattern.posPre);
		    parts.push(formatedText);
		    parts.push(isNegative ? pattern.negSuf : pattern.posSuf);
		    return parts.join('');
	    }

	    return function (amount, currencySymbol) {
		    if (angular.isUndefined(currencySymbol)) currencySymbol = formats.CURRENCY_SYM;
		    return formatNumber(amount, formats.PATTERNS[0], formats.GROUP_SEP, formats.DECIMAL_SEP, getPrecision()).replace(/\u00A4/g, currencySymbol);
	    };
    }]);
    //---------------------------------
    //通用过滤器 end
    //---------------------------------


    //---------------------------------
    //通用表单校验
    //---------------------------------
    var formVaildApp = angular.module('JxApp.form.valid', []);

    function isEmpty(value) {
	    return angular.isUndefined(value) || value === '' || value === null || value !== value;
    }

    //---------------------------------
    //通用表单校验 end
    //---------------------------------
    function htmlDecode(value) {
	    if (value && (value === '&nbsp;' || value === '&#160;' || (value.length === 1 && value.charCodeAt(0) === 160))) {
		    return "";
	    }
	    return !value ? value : String(value).replace(/&gt;/g, ">").replace(/&lt;/g, "<").replace(/&quot;/g, '"').replace(/&amp;/g, "&");
    }

    function htmlEncode(value) {
	    return !value ? value : String(value).replace(/&/g, "&amp;").replace(/\"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
    }

    /**
     * 检查是否为空或者为undefined
     */
    function isBlank(str) {
	    if (str == undefined || trim(str) == '') {
		    return true;
	    }
	    return false;
    }

    /**
     * 删除左右两端的空格
     * @param str
     * @returns
     */
    function trim(str) { //
	    return str.replace(/(^\s*)|(\s*$)/g, "");
    }

    /**
     * 删除左边的空格
     * @param str
     * @returns
     */
    function ltrim(str) { //
	    return str.replace(/(^\s*)/g, "");
    }

    /**
     * 删除右边的空格
     * @param str
     * @returns
     */
    function rtrim(str) { //
	    return str.replace(/(\s*$)/g, "");
    }

    /**
     * 在页面关闭刷新的时候的阻止页面
     * @param array[{test:(function/string),info:"在test结果为true的时候的提示信息"}]
     */
    function leavePage(array) {
	    $(window).bind("beforeunload", function () {
		    var test;
		    for (var i = 0; i < array.length; i++) {
			    if (typeof array[i].test === 'function') {
				    test = array[i].test();
			    } else if (typeof array[i].test === "string") {
				    test = eval(array[i].test);
			    } else {
				    test = array[i].test;
			    }
			    if (test)
				    return array[i].info;
		    }
	    });
    }

    /*IE兼容问题解决*/

    function stopEvent(e) {

	    if (!e) var e = window.event;

	    //e.cancelBubble is supported by IE -
	    // this will kill the bubbling process.
	    e.cancelBubble = true;
	    e.returnValue = false;

	    //e.stopPropagation works only in Firefox.
	    if (e.stopPropagation) e.stopPropagation();
	    if (e.preventDefault) e.preventDefault();

	    return false;
    }

    Array.prototype._indexOf = function (n) {
	    if ("indexOf" in this) {
		    return this["indexOf"](n);
	    }
	    for (var i = 0; i < this.length; i++) {
		    if (n === this[i]) {
			    return i;
		    }
	    }
	    return -1;
    };

    if (!Array.prototype.indexOf) {
	    Array.prototype.indexOf = function (val) {
		    return jQuery.inArray(val, this);
	    };
    }

    /*IE兼容问题解决 end*/

    /*设置某个style为important*/
    (function ($) {
	    if ($.fn.style) {
		    return;
	    }

	    // Escape regex chars with \
	    var escape = function (text) {
		    return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
	    };

	    // For those who need them (< IE 9), add support for CSS functions
	    var isStyleFuncSupported = !!CSSStyleDeclaration.prototype.getPropertyValue;
	    if (!isStyleFuncSupported) {
		    CSSStyleDeclaration.prototype.getPropertyValue = function (a) {
			    return this.getAttribute(a);
		    };
		    CSSStyleDeclaration.prototype.setProperty = function (styleName, value, priority) {
			    this.setAttribute(styleName, value);
			    var priority = typeof priority != 'undefined' ? priority : '';
			    if (priority != '') {
				    // Add priority manually
				    var rule = new RegExp(escape(styleName) + '\\s*:\\s*' + escape(value) + '(\\s*;)?', 'gmi');
				    this.cssText = this.cssText.replace(rule, styleName + ': ' + value + ' !' + priority + ';');
			    }
		    };
		    CSSStyleDeclaration.prototype.removeProperty = function (a) {
			    return this.removeAttribute(a);
		    };
		    CSSStyleDeclaration.prototype.getPropertyPriority = function (styleName) {
			    var rule = new RegExp(escape(styleName) + '\\s*:\\s*[^\\s]*\\s*!important(\\s*;)?', 'gmi');
			    return rule.test(this.cssText) ? 'important' : '';
		    };
	    }

	    // The style function
	    $.fn.style = function (styleName, value, priority) {
		    // DOM node
		    var node = this.get(0);
		    // Ensure we have a DOM node
		    if (typeof node == 'undefined') {
			    return this;
		    }
		    // CSSStyleDeclaration
		    var style = this.get(0).style;
		    // Getter/Setter
		    if (typeof styleName != 'undefined') {
			    if (typeof value != 'undefined') {
				    // Set style property
				    priority = typeof priority != 'undefined' ? priority : '';
				    style.setProperty(styleName, value, priority);
				    return this;
			    } else {
				    // Get style property
				    return style.getPropertyValue(styleName);
			    }
		    } else {
			    // Get CSSStyleDeclaration
			    return style;
		    }
	    };
    })(jQuery);

    //文档加载完后去掉加载层
    $(document).ready(function () {
	    if (document.getElementById("bodyloadinglayer")) {
		    $('#bodyloadinglayer').fadeOut("fast");
	    }
	    document.CURRENT_LOGIN_ID = getCookie('isLoginId') || "NOT_LOGIN_ID";
	    showMessageIfLowLevelBrowser();
    });

    /**
     * 检测用户浏览器，如果是IE8以下，提示用户升级浏览器
     */
    function showMessageIfLowLevelBrowser() {
	    var browser = getWebBrowser();
	    if (browser && browser.match("IE[5-8]{1}")) {
		    showMessage("浏览器版本过低", "为了得到更好的浏览体验,请升级浏览器到IE9及以上。或者使用<a href='http://se.360.cn/' target='_blank' style='text-decoration:underline;'>360浏览器</a>，并开启极速模式后访问。", -1);
	    }
    }

    /**
     *
     * @param httpServices
     * @param configKey 配置的名称
     * @param targetObj 配置依赖的对象
     * @param targetAttr 配置本身
     * @param defaultValue 配置的默认值
     * @param callback 设置配置成功后的回调函数
     *                    （应用于，获取配置之后还需要检查配置值是否有效的情况，
     *                    如开单设置默认客户时需要检查上次设置的那个客户是否停用或删除，
     *                    获取的配置值会当做这个函数的参数传入）
     * setConfig(httpServices,"checkout.manualAddNumber",$scope,'manualAddNumber',true)，这样可以设置$scope.manulAddNumber的配置。
     */
    function setConfig(httpServices, configKey, targetObj, targetAttr, defaultValue, callback) {
	    var userConfigsStr = window.localStorage.userConfigs;
	    if (!userConfigsStr) {
		    userConfigsStr = JSON.stringify([]);
	    }
	    var userConfigs = JSON.parse(userConfigsStr);
	    var config = getObject(userConfigs, 'configKey', configKey);
	    if (!!config) {
		    if (callback) {
			    callback(JSON.parse(config.configValue));
		    } else {
			    targetObj[targetAttr] = JSON.parse(config.configValue);
		    }
	    } else if (!config) {
		    httpServices.post(base + '/admin/pubuser/getUserConfig.ac', {configKey: configKey}).success(function (result) {
			    if (result.statusCode == 1) {
				    if (!!result.object) {
					    config = result.object;
					    if (callback) {
						    callback(JSON.parse(config.configValue));
					    } else {
						    targetObj[targetAttr] = JSON.parse(config.configValue);
					    }
					    removeByKey(userConfigs, 'configKey', config.configKey);
					    userConfigs.push(config);
					    window.localStorage.userConfigs = JSON.stringify(userConfigs);
				    } else {
					    if (callback) {
						    callback(defaultValue);
					    } else {
						    targetObj[targetAttr] = defaultValue;
					    }
				    }
			    }
		    }).error(function (data, status) {
			    if (callback) {
				    callback(defaultValue);
			    } else {
				    targetObj[targetAttr] = defaultValue;
			    }
		    });
	    }

    }

    /** 设置用户配置*/
    function saveConfig(httpServices, configKey, configValue, device) {
	    var userConfigsStr = window.localStorage.userConfigs;
	    if (!userConfigsStr) {
		    userConfigsStr = JSON.stringify([]);
	    }
	    var userConfigs = JSON.parse(userConfigsStr);
	    var config = getObject(userConfigs, 'configKey', configKey);
	    var exist = false;
	    if (!!config) {
		    config.configValue = JSON.stringify(configValue);
	    } else {

		    config = {configKey: configKey, configValue: JSON.stringify(configValue)};
	    }
	    config.device = !device ? 1 : device;
	    httpServices.post(base + '/admin/pubuser/saveOrUpdateUserConfigNew.ac', config, {}, httpServices.REMIND_SILENCE).success(function (result) {
		    if (result.statusCode == 1) {
			    if (!!result.object) {

				    config = result.object;
				    var localConfig = {
					    userId: config.userId,
					    configKey: config.configKey,
					    configValue: config.configValue,
					    device: config.device
				    }
				    removeByKey(userConfigs, 'configKey', localConfig.configKey);
				    userConfigs.push(localConfig);
				    window.localStorage.userConfigs = JSON.stringify(userConfigs);
			    }
		    }
	    });
    }

    function getCookie(name) {
	    var arr, reg = new RegExp("(^| )" + name + "=([^;]*)(;|$)");
	    if (arr = document.cookie.match(reg))
		    return unescape(arr[2]);
	    else
		    return null;
    }

    /**得到所有的用户配置*/
    function getAllConfig() {
	    var oldJSESSIONID = window.localStorage.SID;
	    var aLoginOld = window.localStorage.aLogin;

	    var newJSESSIONID = getCookie('SID');
	    var aLoginNew = getCookie('aLogin');
	    if (!oldJSESSIONID || oldJSESSIONID !== newJSESSIONID || !aLoginOld || aLoginOld !== aLoginNew) {
		    $.ajax({
			    url: base + '/admin/pubuser/getUserConfigs.ac',
			    type: "POST",
			    data: JSON.stringify({device: 1}),
			    contentType: "application/json;charset=UTF-8",
			    dataType: "json",
			    success: function (result) {
				    if (result.statusCode == 1) {
					    if (!!result.object) {
						    userConfigs = result.object;
						    window.localStorage.userConfigs = JSON.stringify(userConfigs);
					    }
				    }
			    }
		    });
		    window.localStorage.SID = newJSESSIONID;
		    window.localStorage.aLogin = aLoginNew;
	    }
    }

    //getAllConfig();
    /**
     * 适用于报表查询切换不同tab时判断查询条件是否发生了实质变化（查询条件多了、少了、条件值改变了等情况）
     * 检查searchParam和curSearchParam中的条件是否相同，存在不同条件就返回true，条件全都相同就返回false.
     *
     * @param {object} searchParam 前一页的查询参数
     * @param {object} curSearchParam 当前页的查询参数
     * @returns {boolean} 是否需要重新查询汇总数据
     */
    function checkQueryParams(searchParam, curSearchParam) {
	    var vCompareContainer = {};
	    var vCurrentEmptyFlag = true;
	    for (propertyName in curSearchParam) {
		    // 循环curSearchParam，将当前查询条件中非空的参数值放入vCompareContainer
		    if (curSearchParam[propertyName] != undefined && curSearchParam[propertyName] != "") {
			    vCurrentEmptyFlag = false;
			    vCompareContainer[propertyName] = curSearchParam[propertyName];
		    }
	    }
	    // 循环从前一页的查询条件searchParam，如果vCompareContainer是空的，且自身的条件不为空，就返回true；
	    // 如果vCompareContainer非空，从中取出参数值，和vCompareContainer中同名参数值比较，如果相等就从vCompareContainer中移除，不相等就返回true
	    for (propertyName in searchParam) {
		    if (vCurrentEmptyFlag) {
			    if (searchParam[propertyName] != undefined && searchParam[propertyName] != "") {
				    return true;
				    //vCompareContainer[propertyName] = searchParam[propertyName];
				    //break;
			    }
		    } else {
			    if (searchParam[propertyName] != undefined && searchParam[propertyName] != "") {
				    if (searchParam[propertyName] === vCompareContainer[propertyName]) {
					    delete vCompareContainer[propertyName];
				    } else {
					    return true;
				    }
			    }
		    }
	    }
	    // 循环结束后，如果vCompareContainer中还有属性，说明查询条件不相等，需要查询汇总数据，返回true
	    var hasProp = false;
	    for (prop in vCompareContainer) {
		    hasProp = true;
		    break;
	    }
	    return hasProp;
    }

    //对于电脑客户端，添加快捷键及右键菜单
    if (typeof process !== "undefined" && process.versions['node-webkit']) {
	    var gui = require('nw.gui');
	    var win = gui.Window.get();
	    document.onkeydown = function (pressed) {
		    //Check CTRL + F5 keys and hard refresh the page
		    if (pressed.ctrlKey === true && pressed.keyCode === 116) {
			    pressed.preventDefault();
			    gui.App.clearCache();
			    win.reloadDev();
			    return false;
			    //Check Shift + F5 keys and refresh ignoring cache
		    } else if (pressed.shiftKey === true && pressed.keyCode === 116) {
			    pressed.preventDefault();
			    gui.App.clearCache();
			    win.reloadIgnoringCache();
			    return false;
			    //Check F5 key and soft refresh
		    } else if (pressed.keyCode === 116) {
			    pressed.preventDefault();
			    win.reload();
			    return false;
			    //Check F12 or Ctrl+Shift+I and display Webkit Dev Tools
		    } else if (pressed.keyCode === 123 || pressed.ctrlKey === true && pressed.shiftKey === true && pressed.keyCode === 73) {
			    pressed.preventDefault();
			    win.showDevTools();
			    return false;
		    }
	    };

	    $(function () {
		    function Menu() {
			    var gui = require('nw.gui'), menu = new gui.Menu()
				    , copy = new gui.MenuItem({
				    label: "复制",
				    click: function () {
					    document.execCommand("copy");
				    }
			    })
				    , cut = new gui.MenuItem({
				    label: "剪切",
				    click: function () {
					    document.execCommand("cut");
				    }
			    })
				    , paste = new gui.MenuItem({
				    label: "粘贴",
				    click: function () {
					    document.execCommand("paste");
				    }
			    })
				    , refresh = new gui.MenuItem({
				    label: "刷新(F5)",
				    click: function () {
					    win.reload();
				    }
			    });

			    menu.append(copy);
			    menu.append(paste);
			    menu.append(cut);
			    menu.append(refresh);

			    return menu;
		    }

		    var menu = new Menu();
		    $(document).on("contextmenu", function (e) {
			    e.preventDefault();
			    var href = undefined;
			    if (e.target !== undefined && (e.target.tagName.toLowerCase() === "a")) {
				    href = e.target.href;
			    } else if (e.target !== undefined && (e.target.parentElement.tagName.toLowerCase() === "a")) {
				    href = e.target.parentElement.href;
			    }
			    if (menu.items.length > 4) {
				    menu.removeAt(0);
			    }
			    if (href) {
				    menu.insert(new gui.MenuItem({
					    label: '在新窗口中打开链接',
					    click: function () {
						    gui.Window.open(href, {
							    position: 'center',
							    width: win.width,
							    height: win.height
						    });
					    }
				    }, 0));

			    }
			    menu.popup(e.originalEvent.x, e.originalEvent.y);
		    });
	    });
    }


    /**
     * 账户是否可用，如果不可用，则为只读状态
     * @param userLoginInfoJSON
     * @param orginReadonly
     * @param accountId
     */
    function isReadonlyBySpendableAccount(userLoginInfoJSON, orginReadonly, accountId) {
	    if (userLoginInfoJSON.paramMap.viewOtherComStore && userLoginInfoJSON.paramMap.viewOtherComStore != 3) {
		    var s = userLoginInfoJSON.paramMap.spendableStorehouseAndAccount;
		    if (s && s.spendableAccountIds && (s.spendableAccountIds.indexOf(accountId) == -1)) {
			    return true;
		    }
	    }
	    return orginReadonly;
    };

    /**
     * 仓库是否可用，如果不可用，则为只读状态
     * @param userLoginInfoJSON
     * @param orginReadonly
     * @param storehouseId
     */
    function isReadonlyBySpendableStorehouse(userLoginInfoJSON, orginReadonly, storehouseId) {
	    if (userLoginInfoJSON.paramMap.viewOtherComStore && userLoginInfoJSON.paramMap.viewOtherComStore != 3) {
		    var s = userLoginInfoJSON.paramMap.spendableStorehouseAndAccount;
		    if (s && s.spendableStorehouseIds && (s.spendableStorehouseIds.indexOf(storehouseId) == -1)) {
			    return true;
		    }
	    }
	    return orginReadonly;
    };


    /**
     * 销售员是否可用，如果不可用，则为只读状态
     * @param userLoginInfoJSON
     * @param orginReadonly
     * @param salerId
     */
    function isReadonlyBySpendableSaler(userLoginInfoJSON, orginReadonly, salerId) {
	    if (userLoginInfoJSON.paramMap.viewOtherComStore && userLoginInfoJSON.paramMap.viewOtherComStore != 3) {
		    var s = userLoginInfoJSON.paramMap.spendableStorehouseAndAccount;
		    if (s && s.spendableUserIds && (s.spendableUserIds.indexOf(salerId) == -1)) {
			    return true;
		    }
	    }
	    return orginReadonly;
    };

    /**
     * 是否开启了出入库的功能
     *
     * @returns {Boolean}
     */
    function isOpenWoutOrWinStore() {
	    //通过userLoginInfoParam数据可以获取到
	    if (userLoginInfoJSON && userLoginInfoJSON.paramMap && userLoginInfoJSON.paramMap.woutOrWinStore &&
		    userLoginInfoJSON.paramMap.woutOrWinStore == 1) {
		    return true;
	    }
	    return false;
    }

    function isOpenApp(appId) {
	    //通过userLoginInfoParam数据可以获取到
	    if (userLoginInfoJSON && userLoginInfoJSON.paramMap) {
		    var appIds = userLoginInfoJSON.paramMap.ownAppIds || [];
		    return appIds.indexOf(appId) != -1;
	    }
	    return false;
    }

    /**
     * 获取小数点
     * @returns
     */
    function getPricePrecision() {
	    //通过userLoginInfoParam数据可以获取到
	    if (userLoginInfoJSON && userLoginInfoJSON.paramMap && userLoginInfoJSON.paramMap.pricePrecision) {
		    return userLoginInfoJSON.paramMap.pricePrecision;
	    }
	    return 2;
    }

    /**
     * 获取拼接在url后面的参数 getQueryString('param1')
     * @param name
     * @returns
     */
    function getQueryString(name) {
	    var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
	    var r = window.location.search.substr(1).match(reg);
	    if (r != null) return unescape(r[2]);
	    return null;
    }

    /**
     * jquery 发送请求默认带上验证cookie信息
     */
    $.ajaxSetup({
	    xhrFields: {
		    withCredentials: true
	    }
    });

    GL_CONS.REPLENISH = [
	    {
		    value: 1,
		    text: '是'
	    }, {
		    value: 0,
		    text: '否'
	    }
    ];

    /**
     * 格式化补货字段
     *    从1 -- > 是
     *    从是 -- > 1
     *
     * @param va
     * @returns
     */
    function formaterReplenish(va) {
	    for (var i = 0; i < GL_CONS.REPLENISH.length; i++) {
		    if (GL_CONS.REPLENISH[i].value == va) {
			    return GL_CONS.REPLENISH[i].text;
		    }
		    if (GL_CONS.REPLENISH[i].text == va) {
			    return GL_CONS.REPLENISH[i].value;
		    }
	    }
	    return "";
    }

    GL_CONS.FPS_EXPORT = {
	    IntelligentReplenishment: {
		    type: 'IntelligentReplenishment'
	    }
    }
    ;

    function editableColumnTip(cellvalue, options, rowObject) {
	    return cellvalue ? cellvalue : '点击选择';
    }

    function editableColumnRemoveTip(cellvalue, options, rowObject) {
	    return cellvalue == '点击选择' ? '' : cellvalue;
    }

    //兼容ie获取event的触发对象
    function getEvtTarget() {
	    return window.event ? (event.target ? event.target : event.srcElement) : null;
    }

    //JH:采购单、JT:采购退货、PF:销售单、TH:销售退货、LS:零售、PB:盘点、DP:调拨
    function getOrderType(ordersSn) {
	    if (ordersSn) {
		    //查看详细 JH:采购单、JT:采购退货、PF:销售单、TH:销售退货、LS:零售、PB:盘点、DP:调拨
		    if (ordersSn.indexOf('JH') >= 0) {
			    return "采购单";
		    } else if (ordersSn.indexOf('JT') >= 0) {
			    return "采购退货单";
		    } else if (ordersSn.indexOf('PF') >= 0) {
			    return "销售单";
		    } else if (ordersSn.indexOf('TH') >= 0) {
			    return "销售退货单";
		    } else if (ordersSn.indexOf('LS') >= 0) {
			    return "零售单";
		    } else if (ordersSn.indexOf('PD') >= 0) {
			    return "库存盘点单";
		    } else if (ordersSn.indexOf('DB') >= 0) {
			    return "库存调拨单";
		    } else if (ordersSn.indexOf('SK') >= 0) {
			    return "收款单";
		    } else if (ordersSn.indexOf('FK') >= 0) {
			    return "付款单";
		    } else if (ordersSn.indexOf('JZ') >= 0) {
			    return "记账单";
		    } else if (ordersSn.indexOf('CX') >= 0) {
			    return "拆卸单";
		    } else if (ordersSn.indexOf('ZZ') >= 0) {
			    return "组装单";
		    } else if (ordersSn.indexOf('RK') >= 0) {
			    return "入库单";
		    } else if (ordersSn.indexOf('CK') >= 0) {
			    return "出库单";
		    } else if (ordersSn.indexOf('WD') >= 0) {
			    return "销货宝订单";
		    } else if (ordersSn.indexOf('CZ') >= 0) {
			    return "充值";
		    }
	    }

	    return '其它';
    }
</script>